﻿using System;
using System.Windows;
using System.Windows.Threading;
using System.IO;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Reflection;

namespace AutoWallpaperChanger
{
    public partial class MainWindow 
    {
        #region Global Variables, Constants
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern Int32 SystemParametersInfo(UInt32 uiAction, UInt32 uiParam, String pvParam, UInt32 fWinIni);
        const int SPI_SETDESKWALLPAPER = 20;
        const int SPIF_UPDATEINIFILE = 0x01;
        const int SPIF_SENDWININICHANGE = 0x02;

        private System.Windows.Forms.NotifyIcon TrayNotify;
        private System.Windows.Forms.ContextMenuStrip ctxTrayMenu;
        private bool isAppExiting = false;

        DispatcherTimer timer;
        private String imageFolderName = string.Empty;
        private String selectedPath = string.Empty;
        int wallpaperCount, seconds, minutes, hours, days;
        bool randomCheck = false;
        bool intervalCheck = true;
        List<WallFileNames> fileList = new List<WallFileNames>();
        #endregion

        #region Constructor
        public MainWindow()
        {
            InitializeComponent();

            if (File.Exists("c:\\WallConfig.txt"))
            {
                ReadFromFile("c:\\WallConfig.txt");
                lbWalls.ItemsSource = fileList;
                CheckTimerInterval();
                AutoChangeWallpaper();
                btnChange.IsEnabled = true;
                btnChangeNow.IsEnabled = true;
            }
            else
            {
                btnChangeNow.IsEnabled = false;
                btnChange.IsEnabled = false;
            }
        }
        #endregion

        #region Window Closing [MainWindow]
        //private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        //{
        //    //When the application is closed, check wether the application is 
        //    //exiting from menu or forms close button
        //    if (!isAppExiting)
        //    {
        //        //if the forms close button is triggered, cancel the event and hide the form
        //        //then show the notification ballon tip
        //        e.Cancel = true;
        //        this.Hide();
        //        TippuTrayNotify.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;
        //        TippuTrayNotify.BalloonTipTitle = "Tippu Tray Notify";
        //        TippuTrayNotify.BalloonTipText = "Tippu Tray Notify has been minimized to the system tray. To open the application, double-click the icon in the system tray.";
        //        TippuTrayNotify.ShowBalloonTip(400);
        //    }
        //}

        private void GlassWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {

        } 
        #endregion

        #region Timer Tick
        void timer_Tick(object sender, EventArgs e)
        {
            if (lbFiles.Items.Count != 0) 
            {
                int fileCount = lbFiles.Items.Count;
                string timerFile = string.Empty;
                if ((bool)chkRandom.IsChecked)
                {
                    timerFile = lbFiles.Items[Convert.ToInt32(new Random().Next(fileCount))].ToString();
                    SetImage(imageFolderName + timerFile);
                }
                else
                {
                    if (wallpaperCount <= fileCount)
                    {
                        timerFile = lbFiles.Items[wallpaperCount].ToString();
                        wallpaperCount++;
                    }
                    if (wallpaperCount == fileCount)
                    {
                        wallpaperCount = 0;
                    }
                    SetImage(imageFolderName + timerFile);
                }
            }
        }
        #endregion

        #region Button Click [Save & Minimize]
        private void btnChange_Click(object sender, RoutedEventArgs e)
        {
            SaveAndMinimizeToTray();
        } 
        #endregion

        #region Button Click [Browse Folder]
        private void btnBrowseFolder_Click(object sender, RoutedEventArgs e)
        {
            FolderBrowserDialog folderDialog = new FolderBrowserDialog();
            DialogResult result = folderDialog.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                selectedPath = folderDialog.SelectedPath;
                btnChange.IsEnabled = true;
                GetFileNames(selectedPath);
                WriteToFile(selectedPath);
                AutoChangeWallpaper();
            }
        }
        #endregion

        #region Button Click [Change Selected]
        private void btnChangeNow_Click(object sender, RoutedEventArgs e)
        {
            if (lbFiles.Items.Count != 0)
            {
                if (lbFiles.SelectedIndex != -1)
                {
                    string fileName = imageFolderName + lbFiles.SelectedItem.ToString();
                    SetImage(fileName);
                }
            }
        }
        #endregion

        #region Window StateChanged [MainWindow]
        private void GlassWindow_StateChanged(object sender, EventArgs e)
        {
            if (this.WindowState == WindowState.Minimized)
            {
                SaveAndMinimizeToTray();
            }
        }
        #endregion

        #region Menu Click [System Tray Settings]
        void mnuSettings_Click(object sender, EventArgs e)
        {
            isAppExiting = false;
            this.Show();
            this.ShowInTaskbar = true;
            this.WindowState = WindowState.Normal;
            TrayNotify.Visible = false;
        }
        #endregion

        #region TrayIcon DoubleClick [System Tray Icon]
        void TrayNotify_DoubleClick(object sender, EventArgs e)
        {
            isAppExiting = false;
            this.Show();
            this.ShowInTaskbar = true;
            this.WindowState = WindowState.Normal;
            TrayNotify.Visible = false;
        }
        #endregion

        #region Menu Click [System Tray Exit]
        void mnuExit_Click(object sender, EventArgs e)
        {
            isAppExiting = true;
            this.Close();
            TrayNotify.Visible = false;
        }
        #endregion

        #region RadioButton Click [Seconds, Minutes, Hours, Days]
        private void radioInterval_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Controls.RadioButton radio = (System.Windows.Controls.RadioButton)sender;
            switch (radio.Name)
            {
                case "radioIntervalSeconds":
                    txtTimerIntervalDays.Text = "0";
                    txtTimerIntervalHours.Text = "0";
                    txtTimerIntervalMinutes.Text = "0";
                    txtTimerIntervalDays.IsEnabled = false;
                    txtTimerIntervalHours.IsEnabled = false;
                    txtTimerIntervalMinutes.IsEnabled = false;
                    txtTimerIntervalSeconds.IsEnabled = true;
                    break;
                case "radioIntervalMinutes":
                    txtTimerIntervalDays.Text = "0";
                    txtTimerIntervalHours.Text = "0";
                    txtTimerIntervalSeconds.Text = "0";
                    txtTimerIntervalDays.IsEnabled = false;
                    txtTimerIntervalHours.IsEnabled = false;
                    txtTimerIntervalMinutes.IsEnabled = true;
                    txtTimerIntervalSeconds.IsEnabled = false;
                    break;
                case "radioIntervalHours":
                    txtTimerIntervalDays.Text = "0";
                    txtTimerIntervalMinutes.Text = "0";
                    txtTimerIntervalSeconds.Text = "0";
                    txtTimerIntervalDays.IsEnabled = false;
                    txtTimerIntervalHours.IsEnabled = true;
                    txtTimerIntervalMinutes.IsEnabled = false;
                    txtTimerIntervalSeconds.IsEnabled = false;
                    break;
                case "radioIntervalDays":
                    txtTimerIntervalHours.Text = "0";
                    txtTimerIntervalMinutes.Text = "0";
                    txtTimerIntervalSeconds.Text = "0";
                    txtTimerIntervalDays.IsEnabled = true;
                    txtTimerIntervalHours.IsEnabled = false;
                    txtTimerIntervalMinutes.IsEnabled = false;
                    txtTimerIntervalSeconds.IsEnabled = false;
                    break;
                default:
                    break;
            }
        }
        #endregion

        #region RadioButton Checked [Seconds, Minutes, Hours, Days]
        private void radioInterval_Checked(object sender, RoutedEventArgs e)
        {
            System.Windows.Controls.RadioButton radio = (System.Windows.Controls.RadioButton)sender;
            switch (radio.Name)
            {
                case "radioIntervalSeconds":
                    txtTimerIntervalDays.IsEnabled = false;
                    txtTimerIntervalHours.IsEnabled = false;
                    txtTimerIntervalMinutes.IsEnabled = false;
                    txtTimerIntervalSeconds.IsEnabled = true;
                    break;
                case "radioIntervalMinutes":
                    txtTimerIntervalDays.IsEnabled = false;
                    txtTimerIntervalHours.IsEnabled = false;
                    txtTimerIntervalMinutes.IsEnabled = true;
                    txtTimerIntervalSeconds.IsEnabled = false;
                    break;
                case "radioIntervalHours":
                    txtTimerIntervalDays.IsEnabled = false;
                    txtTimerIntervalHours.IsEnabled = true;
                    txtTimerIntervalMinutes.IsEnabled = false;
                    txtTimerIntervalSeconds.IsEnabled = false;
                    break;
                case "radioIntervalDays":
                    txtTimerIntervalDays.IsEnabled = true;
                    txtTimerIntervalHours.IsEnabled = false;
                    txtTimerIntervalMinutes.IsEnabled = false;
                    txtTimerIntervalSeconds.IsEnabled = false;
                    break;
                default:
                    break;
            }

        }
        #endregion

        #region CheckBox Click [Random, Interval]
        private void CheckBox_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Controls.CheckBox chk = (System.Windows.Controls.CheckBox)sender;

            switch (chk.Name)
            {
                case "chkInterval":
                    {
                        if ((bool)chk.IsChecked)
                        {
                            intervalCheck = chk.IsChecked.Value;
                            TimerControls(true);
                        }
                        else
                        {
                            intervalCheck = chk.IsChecked.Value;
                            TimerControls(false);
                            txtTimerIntervalDays.Text = "0";
                            txtTimerIntervalHours.Text = "0";
                            txtTimerIntervalMinutes.Text = "0";
                            txtTimerIntervalSeconds.Text = "0";
                        }
                    }
                    break;
                case "chkRandom":
                    {
                        if ((bool)chk.IsChecked)
                        {
                            randomCheck = chk.IsChecked.Value;
                        }
                        else
                        {
                            randomCheck = chk.IsChecked.Value;
                        }
                    }
                    break;
                default:
                    break;
            }
        }
        #endregion

        #region Image MouseLeftButtonDown
        private void wall_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            System.Windows.Controls.Image img = (System.Windows.Controls.Image)sender;
            string[] words = img.Source.ToString().Split(new string[] { "///" }, StringSplitOptions.None);
            string fileName = words[1].Replace("/", "\\");

            SetImage(fileName);
        }
        #endregion

        #region Image MouseLeftButtonDown [Help]
        private void Help_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Window about = new About();
            about.ShowDialog();
        }
        #endregion

        #region CheckTimerInterval
        private void CheckTimerInterval()
        {
            if ((bool)chkInterval.IsChecked)
            {
                TimerControls(true);
                
                #region Days
                if (days == 0)
                {
                    radioIntervalDays.IsChecked = false;
                    txtTimerIntervalDays.Text = days.ToString();
                    txtTimerIntervalDays.IsEnabled = false;
                }
                else
                {
                    radioIntervalDays.IsChecked = true;
                    txtTimerIntervalDays.Text = days.ToString();
                } 
                #endregion

                #region Hours
                if (hours == 0)
                {
                    radioIntervalHours.IsChecked = false;
                    txtTimerIntervalHours.Text = hours.ToString();
                    txtTimerIntervalHours.IsEnabled = false;
                }
                else
                {
                    radioIntervalHours.IsChecked = true;
                    txtTimerIntervalHours.Text = hours.ToString();
                } 
                #endregion

                #region Minutes
                if (minutes == 0)
                {
                    radioIntervalMinutes.IsChecked = false;
                    txtTimerIntervalMinutes.Text = minutes.ToString();
                    txtTimerIntervalMinutes.IsEnabled = false;
                }
                else
                {
                    radioIntervalMinutes.IsChecked = true;
                    txtTimerIntervalMinutes.Text = minutes.ToString();
                } 
                #endregion

                #region Seconds
                if (seconds == 0)
                {
                    radioIntervalSeconds.IsChecked = false;
                    txtTimerIntervalSeconds.Text = seconds.ToString();
                    txtTimerIntervalSeconds.IsEnabled = false;
                }
                else
                {
                    radioIntervalSeconds.IsChecked = true;
                    txtTimerIntervalSeconds.Text = seconds.ToString();
                } 
                #endregion
            }
            else
            {
                TimerControls(false);
                txtTimerIntervalDays.Text = "0";
                txtTimerIntervalHours.Text = "0";
                txtTimerIntervalMinutes.Text = "0";
                txtTimerIntervalSeconds.Text = "0";
            }
        }
        #endregion

        #region TimerControls(bool)
        private void TimerControls(bool bValue)
        {
            radioIntervalDays.IsEnabled = bValue;
            radioIntervalHours.IsEnabled = bValue;
            radioIntervalMinutes.IsEnabled = bValue;
            radioIntervalSeconds.IsEnabled = bValue;
            txtTimerIntervalDays.IsEnabled = bValue;
            txtTimerIntervalHours.IsEnabled = bValue;
            txtTimerIntervalMinutes.IsEnabled = bValue;
            txtTimerIntervalSeconds.IsEnabled = bValue;
        }
        #endregion

        #region ReadFromFile(string)
        private void ReadFromFile(string selectedPath)
        {
            StreamReader SR;
            string fileContent;
            SR = File.OpenText(selectedPath);
            fileContent = SR.ReadLine();
            string[] words = fileContent.Split(';');
            imageFolderName = words[0];
            seconds = Convert.ToInt32(words[1]);
            minutes= Convert.ToInt32(words[2]);
            hours= Convert.ToInt32(words[3]);
            days = Convert.ToInt32(words[4]);
            chkInterval.IsChecked = Convert.ToBoolean(words[5]);
            chkRandom.IsChecked = Convert.ToBoolean(words[6]);
            intervalCheck = Convert.ToBoolean(words[5]);
            randomCheck = Convert.ToBoolean(words[6]);
            GetFileNames(imageFolderName);
            SR.Close();

            #region Days
            if (days == 0)
            {
                radioIntervalDays.IsChecked = false;
                txtTimerIntervalDays.IsEnabled = false;
            }
            else
            {
                radioIntervalDays.IsChecked = true;
                txtTimerIntervalDays.Text = days.ToString();
            }
            #endregion

            #region Hours
            if (hours == 0)
            {
                radioIntervalHours.IsChecked = false;
                txtTimerIntervalHours.IsEnabled = false;
            }
            else
            {
                radioIntervalHours.IsChecked = true;
                txtTimerIntervalHours.Text = hours.ToString();
            }
            #endregion

            #region Minutes
            if (minutes == 0)
            {
                radioIntervalMinutes.IsChecked = false;
                txtTimerIntervalMinutes.IsEnabled = false;
            }
            else
            {
                radioIntervalMinutes.IsChecked = true;
                txtTimerIntervalMinutes.Text = minutes.ToString();
            }
            #endregion

            #region Seconds
            if (seconds == 0)
            {
                radioIntervalSeconds.IsChecked = false;
                txtTimerIntervalSeconds.IsEnabled = false;
            }
            else
            {
                radioIntervalSeconds.IsChecked = true;
                txtTimerIntervalSeconds.Text = seconds.ToString();
            }
            #endregion

        } 
        #endregion

        #region WriteToFile(string)
		private void WriteToFile(string selectedPath)
        {
            seconds = string.IsNullOrEmpty(txtTimerIntervalSeconds.Text)?
                Convert.ToInt32(0):
                Convert.ToInt32(txtTimerIntervalSeconds.Text);
            minutes = string.IsNullOrEmpty(txtTimerIntervalMinutes.Text) ? 
                Convert.ToInt32(0) : 
                Convert.ToInt32(txtTimerIntervalMinutes.Text);
            hours = string.IsNullOrEmpty(txtTimerIntervalHours.Text) ? 
                Convert.ToInt32(0) : 
                Convert.ToInt32(txtTimerIntervalHours.Text);
            days = string.IsNullOrEmpty(txtTimerIntervalDays.Text) ? 
                Convert.ToInt32(0) : 
                Convert.ToInt32(txtTimerIntervalDays.Text);
            StreamWriter SW;
            SW = File.CreateText("C:\\WallConfig.txt");
            imageFolderName = selectedPath.EndsWith("\\") ? selectedPath : selectedPath + "\\";
            SW.WriteLine(
                imageFolderName + 
                ";" + seconds.ToString() + ";" + minutes.ToString() +
                ";" + hours.ToString() + ";" + days.ToString() + ";" + intervalCheck.ToString() +
                ";" + randomCheck.ToString() + ";");
            SW.Close();
        }
        #endregion

        #region SetImage(string)
        public void SetImage(string fileName)
        {
            string tempPath = Environment.GetFolderPath(System.Environment.SpecialFolder.MyPictures) + ".bmp";
            Bitmap theImage = new Bitmap(fileName);
            theImage.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);
            SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, tempPath, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
        }
        #endregion

        #region GetFileNames(string)
        private void GetFileNames(string selectedPath)
        {
            DirectoryInfo Dir = new DirectoryInfo(selectedPath);
            FileInfo[] FileList = Dir.GetFiles("*.*", SearchOption.AllDirectories);
            lbFiles.Items.Clear();
            fileList.Clear();
            foreach (FileInfo FI in FileList)
            {
                string tempFile = FI.Name;
                if (tempFile.Contains("jpg") || tempFile.Contains("jpeg") ||
                    tempFile.Contains("bmp") || tempFile.Contains("png"))
                {
                    lbFiles.Items.Add(FI.Name);
                    fileList.Add(new WallFileNames { ImageUri = FI.FullName });
                }
            }
        } 
        #endregion

        #region AutoChangeWallpaper
        private void AutoChangeWallpaper()
        {
            timer = new DispatcherTimer();

            if (seconds != 0)
            {
                timer.Interval = TimeSpan.FromSeconds(seconds);
                timer.Tick += new EventHandler(timer_Tick);
                timer.Start();
            }
            else if (minutes != 0)
            {
                timer.Interval = TimeSpan.FromMinutes(minutes);
                timer.Tick += new EventHandler(timer_Tick);
                timer.Start();
            }
            else if (hours != 0)
            {
                timer.Interval = TimeSpan.FromHours(hours);
                timer.Tick += new EventHandler(timer_Tick);
                timer.Start();
            }
            else if (days != 0)
            {
                timer.Interval = TimeSpan.FromDays(days);
                timer.Tick += new EventHandler(timer_Tick);
                timer.Start();
            }
        }
        #endregion

        #region SaveAndMinimizeToTray
        private void SaveAndMinimizeToTray()
        {
            if (lbFiles.Items.Count != 0)
            {
                WriteToFile(imageFolderName);
                ReadFromFile("C:\\WallConfig.txt");
                AutoChangeWallpaper();
            }

            TrayNotify = new System.Windows.Forms.NotifyIcon();
            TrayNotify.Icon = new System.Drawing.Icon(Assembly.GetExecutingAssembly().Location + "..\\..\\Application.ico");
            TrayNotify.Visible = true;
            ctxTrayMenu = new System.Windows.Forms.ContextMenuStrip();

            System.Windows.Forms.ToolStripMenuItem mnuExit = new System.Windows.Forms.ToolStripMenuItem();
            mnuExit.Text = "Exit";
            mnuExit.Click += new EventHandler(mnuExit_Click);

            System.Windows.Forms.ToolStripMenuItem mnuSettings = new System.Windows.Forms.ToolStripMenuItem();
            mnuSettings.Text = "Settings";
            mnuSettings.Click += new EventHandler(mnuSettings_Click);

            ctxTrayMenu.Items.Add(mnuSettings);
            ctxTrayMenu.Items.Add("-");
            ctxTrayMenu.Items.Add("-");
            ctxTrayMenu.Items.Add(mnuExit);

            TrayNotify.DoubleClick += new EventHandler(TrayNotify_DoubleClick);

            TrayNotify.ContextMenuStrip = ctxTrayMenu;

            this.WindowState = WindowState.Minimized;
            this.ShowInTaskbar = false;

            TrayNotify.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;
            TrayNotify.BalloonTipTitle = "Auto Change Wallpaper";
            TrayNotify.BalloonTipText = "Your Settings have been saved.";
            TrayNotify.ShowBalloonTip(200);
        }
        #endregion
    } 

    #region Class WallFileNames
    public class WallFileNames
    {
        public string ImageUri { get; set; }
    } 
    #endregion
}
